package com.xqboss.apps.controller.market;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xqboss.apps.domain.param.AesParams;
import com.xqboss.apps.dto.IdDto;
import com.xqboss.apps.dto.category.CategoryDto;
import com.xqboss.apps.dto.market.*;
import com.xqboss.apps.enums.category.CategoryNftTypeEnum;
import com.xqboss.apps.enums.market.MarketTypeEnum;
import com.xqboss.apps.enums.user.UserWalletEnum;
import com.xqboss.apps.service.consumer.ConsumerRealNameService;
import com.xqboss.apps.service.market.MarketService;
import com.xqboss.apps.service.nft.CategoryService;
import com.xqboss.apps.service.user.YeepayWalletService;
import com.xqboss.apps.vo.category.CategoryAppVo;
import com.xqboss.apps.vo.market.*;
import com.xqboss.common.annotation.RateLimiter;
import com.xqboss.common.annotation.RepeatSubmit;
import com.xqboss.common.core.controller.BaseController;
import com.xqboss.common.core.domain.PageResult;
import com.xqboss.common.core.domain.R;
import com.xqboss.common.enums.LimitType;
import com.xqboss.common.utils.ValidatorUtil;
import com.xqboss.common.utils.aes.AesUtil;
import com.xqboss.system.service.ISysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.util.List;

/**
 * @author Administrator
 */
@Api(tags = "市场")
@RestController
@RequestMapping("/apps/market")
@Slf4j
public class MarketController extends BaseController {

    @Autowired
    private MarketService marketService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private YeepayWalletService yeepayWalletService;

    @Autowired
    private ConsumerRealNameService realNameService;

    @ApiOperation("获取筛选条件")
    @GetMapping("filter/{nftType}")
    public R<List<CategoryAppVo>> filter(@ApiParam(name = "nftType",value = "分类类型（1藏品 2装备 3箱子）",readOnly = true) @NotNull(message = "分类类型不能为空") @PathVariable CategoryNftTypeEnum nftType) {
        List<CategoryAppVo> list = categoryService.selectCategoryListNftApp(CategoryDto.builder().nftType(nftType).online(1).build());
        return R.ok(list);
    }


    @RateLimiter(key="market:", time = 1 * 60 * 60, count = 1500, limitType = LimitType.USER_ID)
    @ApiOperation("典藏、装备、宝盒列表")
    @GetMapping("list")
    public PageResult<MarketListVo> list(@Validated MarketDto<MarketListVo> dto) {
        if(dto.getType() != MarketTypeEnum.EQUIPMENT)dto.setLossDegree(null);
        IPage<MarketListVo> iPage = marketService.marketListPlus(dto,10);
        return PageResult.ok(iPage);
    }

    @RateLimiter(key="market:", time = 1 * 60 * 60, count = 1500, limitType = LimitType.USER_ID)
    @ApiOperation("典藏、装备、宝盒扩展")
    @GetMapping("list-extend")
    public R listExtend(@Validated MarketExtendDto dto) {
        return marketService.marketExtenList(dto);
    }

    @ApiOperation("转卖记录(典藏、装备、宝盒、材料)")
    @GetMapping("resell-record")
    public R resellRecord(@Validated MarketResellDto dto) {
        Long userId = getUserId();
        switch (dto.getStatus()) {
            case TRADING:
            case CANCEL:
                return marketService.resellRecord(dto, userId);

            case SOLD_OUT:
            case TRADE:
                return marketService.resellRecord2(dto, userId);

            default:
                return R.fail("市场状态错误");
        }
    }

    @ApiOperation("转卖记录(宝盒、材料)详情")
    @GetMapping("resell-record-boxInfo")
    public R<List<MarketResellBoxInfoVo>> resellRecordBoxInfo(@Validated MarketBoxInfoDto dto) {
        return marketService.resellRecordBoxInfo(dto, getUserId());
    }


    @ApiOperation("预上架市场信息")
    @PostMapping("pre-add-info")
    public R<PreAddMarketVo> preAddInfo(@Validated @RequestBody PreAddMarketDto dto) {
        PreAddMarketVo vo = marketService.preAddInfo(getUserId(), dto);
        return R.ok(vo);
    }

    @RepeatSubmit(interval = 1000, justUrl = true)
    @ApiOperation("上架市场")
    @PostMapping("add-market")
    public R addMarket(@Validated @RequestBody AesParams params){
        AddMarketDto dto = AesUtil.decryptToObject(params.getParamStr(), AddMarketDto.class);
        log.info("解密结果：{}" , JSON.toJSONString(dto));
        ValidatorUtil.valid(dto);
        // 验证实名
        realNameService.requireRealName(getUserId());
        // 校验支付密码
        userService.checkPayPwd(getUserId(), dto.getPayPassword());
        // 验证开通易宝钱包
        yeepayWalletService.requireWallet(getUserId());
        marketService.addMarket(getUserId(), dto);
        return R.ok();
    }

    @RepeatSubmit(interval = 1000, justUrl = true)
    @ApiOperation("下架市场")
    @PostMapping("cancel-market")
    public R cancelMarket(@Validated @RequestBody IdDto dto) {
        marketService.cancelSaleable(getUserId(), dto.getId());
        return R.ok();
    }

    @ApiOperation("获取用户剩余转卖次数")
    @GetMapping("residue-resale-count")
    public R<ResidueResaleCountVo> residueResaleCount(@Validated GetResidueResaleCountDto dto) {
        ResidueResaleCountVo vo = new ResidueResaleCountVo();
        // 扳手额外处理
        if (dto.getSourceId() != null){
            if (dto.getSourceId() == UserWalletEnum.WRENCH.getValue().longValue()){
                Integer residueResaleCount = marketService.getWrenchResidueResaleCount(getUserId());
                vo.setResidueResaleCount(residueResaleCount);
                return R.ok(vo);
            }
            if (dto.getSourceId() == UserWalletEnum.LIDOU.getValue().longValue()){
                Integer residueResaleCount = marketService.getLidouResidueResaleCount(getUserId());
                vo.setResidueResaleCount(residueResaleCount);
                return R.ok(vo);
            }
        }
        Integer residueResaleCount = marketService.getResidueResaleCount(dto.getType(), getUserId());
        vo.setResidueResaleCount(residueResaleCount);
        return R.ok(vo);
    }

    @ApiOperation("市场获取nft/宝盒详情")
    @PostMapping("nft-info/{marketId}")
    public R<MarketInfoVo> nftInfo(@Validated @PathVariable("marketId")
                                       @ApiParam(value = "市场编号", required = true)
                                       @NotNull(message = "市场编号不能为空")
                                       Long marketId) {
        return marketService.marketNftInfo(marketId);
    }

    @ApiOperation("市场顶部-市场热豆、扳手交易最低价")
    @GetMapping("hotBeans-minPrice")
    public R<HotBeansVo> hotBeansMinPrice() {
        return marketService.hotBeansMinPrice();
    }

}
